/* -+- file  ./kf2/Core/Util.cs -+- */
/*
 * kf2 jabber client
 * ~~~~~~~~~~~~~~~~~
 *
 * Copyright (C) 2006-2007 Przemysław Sitek
 * 				<przemyslaw.sitek at wp.pl> 
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this program; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

using System;
using System.IO;
using System.Text;
using System.Diagnostics;	// for process spawning
using System.Media;		// for media playback
using Mono.Unix;

namespace Habazie.kf2.Core
{
	///<summary>Core utilities</summary>
	public class Util
	{
		private static App m_App;
		
		public const string APPNAME = "talkative";
		public const string VERSION = "0.5";
		
		static Util ()
		{
			m_lastSound = DateTime.Now;
		}
		
#region Debugging utilities
		
		///<summary>issue debug message</summary>
		public static void Debug (string module, object str)
		{
			Console.Error.Write ("kf2:{0}: ", module);
			Console.Error.WriteLine (str.ToString ());
		}
		
		///<summary>Iddue debug message</summary>
		public static void Debug (string module, string format, params object [] p)
		{
			Console.Error.Write ("kf2:{0}: ", module);
			Console.Error.WriteLine (format, p);
		}
		
		///<summary>
		///	Report an exception
		///</summary>
		public static void ReportException (Exception e)
		{
			Console.Error.WriteLine ("kf2:Caught exception: @{1}.{2}\n * {3}: {0}",
			e.Message, e.TargetSite.DeclaringType, e.TargetSite.Name, e.GetType ().ToString ());
			Console.Error.WriteLine ("{0}", e.StackTrace);
		}
		
#endregion

		///<summary>Find a file in application's data directory</summary>
		public static string FindFile (string name)
		{
			string base_directory = System.AppDomain.CurrentDomain.BaseDirectory;
			return System.IO.Path.Combine (base_directory, name);
//			return "/home/przemek/talkative/kf2/data/"string base_directory = System.AppDomain.CurrentDomain.BaseDirectory; + name;
		}
		
		///<summary>Find a file in user home directory</summary>
		public static string UserFile (string name)
		{
			Mono.Unix.UnixUserInfo user = Mono.Unix.UnixUserInfo.GetRealUser ();
			string homedir = System.IO.Path.Combine (user.HomeDirectory, ".talkative");
			if (! System.IO.Directory.Exists (homedir))
				System.IO.Directory.CreateDirectory (homedir);
			return System.IO.Path.Combine (homedir, name);
		}
		
		public static App Application {
			get { return m_App; }
		}
		
		///<summary>Application configuration</summary>
		public static IConfiguration Config {
			get { return m_App.Configuration; }
		}
		
		///<summary>Save reference to application object</summary>
		internal static void StoreApp (App a) {
			m_App = a;
		}
		
#region Miscallenous functions
	public static string StatusToString (jabber.protocol.client.PresenceType presence, string show)
	{
		if (presence == jabber.protocol.client.PresenceType.unavailable)
			return Catalog.GetString ("Disconnected");
		else {
			if (show == null || show == "")
				return Catalog.GetString ("Online");
			else if (show == "away")
				return Catalog.GetString ("Away");
			else if (show == "xa")
				return Catalog.GetString ("Extended Away");
			else if (show == "dnd")
				return Catalog.GetString ("Do Not Disturb");
			else if (show == "chat")
				return Catalog.GetString ("Chat With Me!");
		}
		// should not happen...
		return show;
	}
	
		private static string m_os = null;
		
		/// <summary>
		/// 	Return operating system information string 	
		/// </summary>
		public static string OperatingSystem {
			get {
				if (Util.m_os == null) {
					try {
						FileStream fs = new FileStream ("/etc/lsb-release",
									FileMode.Open, FileAccess.Read);
						StreamReader reader = new StreamReader (fs);
						string line;
						while ((line = reader.ReadLine ()) != null) {
							if (line.StartsWith ("DISTRIB_DESCRIPTION=")) {
								string os_info = line.Substring (20);
								Util.m_os = os_info;
							}
						}
						reader.Close ();
						fs.Close ();
					} catch {
					}
				}
				return Util.m_os;
			}
		}
		
		public static string EscapeString (string str)
		{
			StringBuilder b = new StringBuilder ();
			foreach (char c in str) {
				switch (c) {
					case '<':	b.Append ("&lt;"); break;
					case '>':	b.Append ("&gt;"); break;
					case '&':	b.Append ("&amp;"); break;
					default:	b.Append (c); break;
				}
			}
			return b.ToString ();
		}
#endregion
#region Aural features

		static DateTime m_lastSound;
		
		public static string GetSoundFile (string name)
		{
			string filename = Util.Config.GetString ("sounds/"+name);
			if (filename == null || filename.Length == 0)
				filename = name+".wav";

			if (! System.IO.Path.IsPathRooted (filename))
				filename = Util.FindFile ("sounds/"+filename);

			return filename;
		}


		/// <summary>
		/// 	Play a sound
		/// </summary>
		public static void PlaySound (string name)
		{
			if (! Util.Config.GetBool ("sound-enabled"))
				return;

			TimeSpan span = DateTime.Now - m_lastSound;
			m_lastSound = DateTime.Now;
			if (span.TotalSeconds <= 3)		// prevent flooding of sounds
				return;
				
			string filename = Util.GetSoundFile (name);
			Util.PlaySoundFile (filename);
		}


		/// <summary>
		/// 	Play a sound file
		/// </summary>
		public static void PlaySoundFile (string file)
		{
			if (Util.Config.GetBool ("sound-use-external-player")) {
				string player = Util.Config.GetString ("sound-external-player");
				if (player == null)
					player = "aplay";

				Process.Start (player, file);
			} else {
//				SoundPlayer player = new SoundPlayer (file);
				try {
					SoundPlayer player = new SoundPlayer (new FileStream (file, FileMode.Open, FileAccess.Read));
					player.Play ();
				} catch {
				}
			}
		}
#endregion
	}
	
}
